import { onUnmounted, ref, watch } from 'vue';
import type { RouteLocationNormalized } from 'vue-router';
import { useRoute } from 'vue-router';

type RouteChangeCallback = (newRoute: RouteLocationNormalized, oldRoute: RouteLocationNormalized) => void;

/**
 * 自定义钩子，用于监听路由变化并执行回调函数
 * 主要解决在特定组件中监听路由变化的需求
 *
 * @param callback 路由变化时的回调函数，接收新旧路由作为参数
 * @returns 返回一个对象，包含停止监听路由变化的方法
 */
export function useRouteChange(callback: RouteChangeCallback) {
  // 获取当前路由
  const route = useRoute();

  // 创建监听器
  const stopWatch = watch(
    // 监听路由的fullPath属性变化
    () => route.fullPath,
    // 新旧路径变化时的处理函数
    (newPath, oldPath) => {
      // 获取完整路由对象
      const newRoute = route;
      // 构造旧路由对象，确保fullPath属性反映变化前的路径
      const oldRoute = { ...route, fullPath: oldPath } as RouteLocationNormalized;

      // 调用回调函数，传递新旧路由对象
      callback(newRoute, oldRoute);
    },
    // 配置监听器在组件更新后触发，并立即触发一次
    { flush: 'post', immediate: true },
  );

  // 组件卸载时自动停止监听
  onUnmounted(() => {
    stopWatch();
  });

  // 返回停止监听的方法（可选）
  return {
    stop: stopWatch,
  };
}

/**
 * 获取当前路由参数
 * @returns 当前路由参数
 */
export function useRouteQuery<T>() {
  const route = useRoute();

  // 创建一个响应式对象来存储路由参数
  const query = ref<T>(route.query as T);

  // 监听路由参数的变化
  watch(
    () => route.query,
    (newParams) => {
      // 更新响应式对象
      query.value = newParams;
    },
    { immediate: true }, // 立即触发一次
  );

  return query; // 返回当前路由参数
}
